home *** CD-ROM | disk | FTP | other *** search
/ Your Choice 3 / Your Choice Software Collection 3.iso / prgmming / swag08 / xx3402 / xx3402.how < prev    next >
Text File  |  1994-01-27  |  8KB  |  226 lines

  1.  
  2.  
  3.   HOW XX34 WORKS
  4.  
  5.   The basic premise behind most binary to ASCII encoder/decoders
  6.   is to convert an element from a larger range of values, to an
  7.   element from a smaller value range.
  8.  
  9.   ...Huh? ...Say what?
  10.  
  11.   In other words, you take a binary byte that could have a value
  12.   between 0..255, and you convert it to an ASCII character that
  13.   can have one of 64 values between '+'..'z' (#43..#122).
  14.  
  15.   ...Ok, but a binary byte has a range of 256 different values,
  16.   how can you convert this to an ASCII character that has a range
  17.   of only 64 different values, and ever hope of getting the
  18.   original byte value back again?
  19.  
  20.   The "magic" (logic) relies on those little itty bitty bits that
  21.   make up each byte.
  22.  
  23.   Each byte is made up of 8 bits. Each bit can have a value
  24.   of either 0 or 1, which gives us a total of 256 different
  25.   combinations for each group of 8 bits.
  26.  
  27.     ie: 2 raised to the power of 8 = 256
  28.  
  29.   Now what if we took 24 bits (3 bytes), and split them up into
  30.   four groups of 6 bits. Visually it would look something like
  31.   this:
  32.  
  33.     Three 8-bit groups:    ||||||||   ||||||||   ||||||||
  34.     (256 combinations)
  35.  
  36.     ...becomes...
  37.  
  38.     Four 6-bit groups:     ||||||  ||||||  ||||||  ||||||
  39.     (64 combinations)
  40.  
  41.   Each 6 bit group would then have a range of 64 different
  42.   combinations, (2 raised to the power of 6 = 64) and this
  43.   range fits within the ASCII character range of '+'..'z'.
  44.  
  45.     ie: (256 x 256 x 256) = (64 x 64 x 64 x 64)
  46.            8-Bit Groups        6-Bit Groups
  47.  
  48.   So by processing a binary file in 3 byte chunks, and splitting
  49.   ("encoding") the 24 bits that these three bytes contain into
  50.   four 6 bit groups, you can represent 3 binary bytes using 4
  51.   standard alpha-numeric ASCII characters from a total set of
  52.   64 ASCII characters.
  53.  
  54.   By reversing this process ("decoding"), you can rebuild the
  55.   original 3 bytes, from the 4 ASCII characters that your
  56.   encoder produced.
  57.  
  58.   ...So if you were encoding three 8-bit groups that were:
  59.  
  60.   Byte value :       255        240        15
  61.   Bit pattern:    11111111   11110000   00001111
  62.  
  63.   ...You would end up with four 6-bit groups that are:
  64.  
  65.   Byte value :      63        63         0        15
  66.   Bit pattern:    111111    111111    000000    001111
  67.  
  68.   ...Now by defining a Pascal 64 ASCII character array like so:
  69.  
  70.     type
  71.       Array64 = array[0..63] of char;
  72.  
  73.   ...And using this "Array64" type to define a "typed constant" :
  74.  
  75.     const
  76.       EncodedSet : Array64 =
  77.  
  78.   '+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
  79.  
  80.   You can then translate those initial three 8-bit numbers,
  81.   (255, 240, 15) into four 6-bit numbers (63, 63, 0, 15).
  82.  
  83.   NOTE: Turbo Pascal allows you to move bits around by using the
  84.         "SHL" and "SHR" operators.
  85.  
  86.         The "AND" operator is necessary to "mask-out" specific
  87.         "high" bits, and stop bytes from from "over-flowing" the
  88.         valid byte number range.
  89.  
  90.         The "OR" operator combines the "masked" bit-patterns back
  91.         into a single byte value.
  92.  
  93.  
  94.         BinByte1 := 255;
  95.         BinByte2 := 240;
  96.         BinByte3 :=  15;
  97.  
  98.         TempByte1 := BinByte1 shr 2;
  99.  
  100.         TempByte2 := ((BinByte1 AND 3) SHL 4) OR (BinByte2 SHR 4);
  101.  
  102.         TempByte3 := ((BinByte2 AND 15) SHL 2) OR (BinByte3 SHR 6);
  103.  
  104.         TempByte4 := BinByte3 AND 63;
  105.  
  106.   ...And finally into four standard ASCII characters:
  107.  
  108.       EncodedChar1 := EncodedSet[TempByte1];   (* ASCII char = 'z' *)
  109.       EncodedChar2 := EncodedSet[TempByte2];   (* ASCII char = 'z' *)
  110.       EncodedChar3 := EncodedSet[TempByte3];   (* ASCII char = '+' *)
  111.       EncodedChar4 := EncodedSet[TempByte4];   (* ASCII char = 'C' *)
  112.  
  113.   ...So after you've encoded the 3 bytes, you end up with the four
  114.   ASCII chars, 'zz+C'.
  115.  
  116.   By reversing this process ("decoding"), you can rebuild the
  117.   original 3 bytes, from the 4 ASCII characters that your encoder
  118.   produced. To make this a simple/quick process, we could build
  119.   the following "look-up" (translation) table:
  120.  
  121.     type
  122.       Byte80 = array[43..122] of byte;
  123.  
  124.     const
  125.       BinSet : Byte80 = ( 0,  0,  1,  0,  0,  2,  3,  4,  5,  6,
  126.                           7,  8,  9, 10, 11,  0,  0,  0,  0,  0,
  127.                           0,  0, 12, 13, 14, 15, 16, 17, 18, 19,
  128.                          20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  129.                          30, 31, 32, 33, 34, 35, 36, 37,  0,  0,
  130.                           0,  0,  0,  0, 38, 39, 40, 41, 42, 43,
  131.                          44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
  132.                          54, 55, 56, 57, 58, 59, 60, 61, 62, 63);
  133.  
  134.   ...So to get my original four 6-bit numbers back:
  135.  
  136.       TempByte1 := BinSet[ord('z')];   (* TempByte = 63 *)
  137.       TempByte2 := BinSet[ord('z')];   (* TempByte = 63 *)
  138.       TempByte3 := BinSet[ord('+')];   (* TempByte =  0 *)
  139.       TempByte4 := BinSet[ord('C')];   (* TempByte = 15 *)
  140.  
  141.   ...and then translate these four 6-bit numbers (63, 63, 0, 15)
  142.   back into three 8-bit numbers (255, 240, 15):
  143.  
  144.       BinByte1 := (TempByte1 SHL 2) OR (TempByte2 SHR 4);
  145.  
  146.       BinByte2 := ((TempByte2 AND 15) SHL 4) OR (TempByte3 SHR 2);
  147.  
  148.       BinByte3 := ((TempByte3 and 3) SHL 6) OR (TempByte4 AND 63);
  149.  
  150.  
  151.   TURNING THEORY INTO REALITY
  152.  
  153.   So now that we all know how the process works, we need to put
  154.   the theory into a finished program.
  155.  
  156.   First of all we need to create two data buffers. One to hold
  157.   the original binary file data, and another to hold the encoded
  158.   data. Buffers are needed because, your program will be as fast
  159.   as a salted slug if you don't buffer the data being read/written
  160.   to/from disk. (ie: Disk I/O is MUCH slower than moving data
  161.   around in RAM.)
  162.  
  163.   To simplify the encoding/decoding process a little, we'll set
  164.   the size of these two buffers by determining the size of the
  165.   largest binary/encoded text block we want to encode/decode.
  166.   In this case the largest encoded text block is 100 columns by
  167.   200 rows of text:
  168.  
  169.     Encoded text block size     : (200 rows) * (100 columns)
  170.     Plus the CrLf's for each row: (200 rows) * 2 bytes
  171.    ===========================================================
  172.     Total = 20,400 bytes
  173.  
  174.   ...Next we need to calculate the binary block buffer:
  175.  
  176.     Binary block size: (200 rows) * (100 columns) * 3/4
  177.     =========================================================
  178.     Total = 15,000 bytes
  179.  
  180.   Once the buffers sizes have been determined, the complete
  181.   encoding process would be something like this:
  182.  
  183.    1- Open binary file.
  184.  
  185.    2- Open the encoded text file.
  186.  
  187.    3- Load the binary file into the binary buffer.
  188.  
  189.    4- Encode from binary buffer to encoded text buffer.
  190.  
  191.    5- Once a complete binary-block has been encoded, write
  192.       the encoded text buffer out to the encoded text file.
  193.  
  194.    6- Repeat steps 3-5 until the entire binary file has been
  195.       completely encoded.
  196.  
  197.    7- Close files.
  198.  
  199.  
  200.   ...The Decoding process is pretty much the same in reverse.
  201.  
  202.    1- Open encoded text file.
  203.  
  204.    2- Open binary file.
  205.  
  206.    3- Load encoded text buffer from encoded text file.
  207.  
  208.    4- Decode from the encoded text buffer to binary buffer.
  209.  
  210.    5- Once a complete binary block has been decoded, write
  211.       the binary buffer out to the new binary file.
  212.  
  213.    6- Repeat steps 3-5 until the entire binary file has been
  214.       completely decoded.
  215.  
  216.    7- Close files.
  217.  
  218.   This is a great simplification of the complete process,
  219.   though it should give you the basic idea of how the
  220.   binary/text encoding/decoding process works. For a more
  221.   detailed look, take a look at the included XX3402.PAS
  222.   source-code included with this archive.
  223.  
  224.                                - Guy
  225.  
  226.